# -*- coding: utf8 -*-
#
# Copyright (c) 2009 Matías Ribecky <status-notifications@mribecky.com.ar>
#
# This file is part of status-notifications.
# 
# status-notifications is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# status-notifications is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with status-notifications.  If not, see <http://www.gnu.org/licenses/>.

'''Notifies of new updates as they are created.'''

import cgitb
cgitb.enable(format='text')

import sys
import time
import operator
import logging

import pluginlib

import statusnotifications.config
import statusnotifications.data
import statusnotifications.notifiers.libnotify
import statusnotifications.notifiers.stdout

LOGGER = logging.getLogger('statusnotifications.main')

def main(argv):
    '''Configure, setup and run the main loop.'''

    sys.excepthook = lambda exc_type, exc, tbk: exit_cause_exception(exc, tbk)

    plug_mgr = _load_plugins()

    providers, notifier, sleep_time = statusnotifications.config.load(argv,
                                                                      plug_mgr)

    while True:
        try:
            for provider in providers:
                check_new_statuses(provider, notifier)
        except plug_mgr.get_interface('NetworkError'), exc:
            LOGGER.exception('Network error: %s' % exc)

        time.sleep(sleep_time * 60)

    return 0

def exit_cause_exception(exc, tbk):
    '''Log error and exit.'''

    try:
        raise exc, None, tbk
    except Exception, exc:
        LOGGER.exception('Unexpected error')
        print >> sys.stderr, 'error:', str(exc)
        sys.exit(1)

def _load_plugins():
    logging.basicConfig(level=logging.DEBUG)

    plug_mgr = pluginlib.PluginManager(statusnotifications.data.PLUGIN_PATH)
    for plugin in plug_mgr.plugins.values():
        try:
            plugin.load()
        except pluginlib.PluginError:
            continue

    for plugin in plug_mgr.plugins.values():
        plugin.activate()

    return plug_mgr

def check_new_statuses(provider, notifier):
    '''Fetches statuses and notifies the new ones.'''

    LOGGER.info("Fetching statuses")
    statuses = sorted(provider.get_new_statuses(),
                      key=operator.attrgetter('date'))
    for status in statuses:
        LOGGER.debug("Found new status %s of '%s'" %
                     (status.id, status.user.user_name))
        notifier.notify(status)

    return True # don't unregister callback

if __name__ == '__main__':
    sys.exit(main(sys.argv))
